﻿#region Copyright

// /*
// SilverlightInEnterprise
// SilverlightInEnterprise
// ActiveScreensTabControl.cs
// 
// Author: Matt Van Horn
// Created 11/15/2011 10:11 PM
// Copyright: Silverlight in the Enterprise www.slinenterprise.com
// 
// Licensed under MS-PL http://www.opensource.org/licenses/MS-PL and while you 
// may use this in anyway you see fit and owe us nothing to do so, we wouldn't mind knowing that you got value out of the work we did (so we will do more) so 
// we ask that you leave a comment on www.slinenterprise.com or on the codeplex site slinenterprise.codeplex.com
// 
// */

#endregion

using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using SilverlightInEnterprise.Interfaces.Screens;

namespace SilverlightInEnterprise.Controls
{
    public class ActiveScreensTabControl : TabControl
    {
        #region ActiveScreens 

        public static readonly DependencyProperty ActiveScreensProperty =
            DependencyProperty.Register("ActiveScreens", typeof (ReadOnlyObservableCollection<IScreen>),
                                        typeof (ActiveScreensTabControl),
                                        new PropertyMetadata(ActiveScreensProperty_ChangedCallback));

        public ReadOnlyObservableCollection<IScreen> ActiveScreens
        {
            get { return (ReadOnlyObservableCollection<IScreen>) GetValue(ActiveScreensProperty); }
            set { SetValue(ActiveScreensProperty, value); }
        }

        /// <summary>
        ///   DP changed call back for ActiveScreens
        /// </summary>
        /// <param name = "obj">instance of ActiveScreensTabControl that is having its ActiveScreens property changed</param>
        /// <param name = "e">the DP changed arguments</param>
        private static void ActiveScreensProperty_ChangedCallback(DependencyObject obj,
                                                                  DependencyPropertyChangedEventArgs e)
        {
            ActiveScreensTabControl element = obj as ActiveScreensTabControl;

            element.OnActiveScreensChanged(e);
        }

        /// <summary>
        ///   Method will enable classes that derive from ActiveScreensTabControl to handle ActiveScreens changes
        /// </summary>
        /// <param name = "e">the DP changed arguments passed in to the DP changed callback</param>
        protected virtual void OnActiveScreensChanged(DependencyPropertyChangedEventArgs e)
        {
            INotifyCollectionChanged changed = this.ActiveScreens;
            changed.CollectionChanged += OnActiveScreensCollectionChanged;
            this.ActiveScreens.ToList().ForEach(s => this.tabs.Add(this.GetTab(s)));
        }

        private void OnActiveScreensCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    this.tabs.Add(this.GetTab(e.NewItems[0] as IScreen));
                    break;
                case NotifyCollectionChangedAction.Remove:
                    this.tabs.RemoveAt(e.OldStartingIndex);
                    break;
                case NotifyCollectionChangedAction.Replace:
                    this.tabs[e.OldStartingIndex].DataContext = e.NewItems[0];
                    break;
                case NotifyCollectionChangedAction.Reset:
                    this.tabs.Clear();
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }

        #endregion

        private readonly ObservableCollection<TabItem> tabs = new ObservableCollection<TabItem>();

        public ActiveScreensTabControl()
        {
            this.SetBinding(ItemsControl.ItemsSourceProperty, new Binding() {Source = this.tabs});
        }

        private TabItem GetTab(IScreen screen)
        {
            TabItem tab = new TabItem()
                              {
                                  DataContext = screen
                                  // ,HeaderTemplate = this.Resources["DataTemplate1"] as DataTemplate
                                  //        Style = this.Resources["ActiveScreenTabStyle"] as Style
                              };
            tab.SetBinding(TabItem.HeaderProperty, new Binding("DisplayName"));
            return tab;
        }
    }
}